#pragma once

#include <map>
#include <vector>
#include "common.h"

template<class TConfiguration, class TResult>
class ResultStorage
{
public:
	virtual void store(const TConfiguration &c, const TResult &r) = 0;
};

template
<
	class TGenerator, 
	class TResult = int, 
	class Comparer = typename generator_traits<TGenerator>::ConfigurationComparer
>
class SimpleResultStorage 
	: public ResultStorage<typename generator_traits<TGenerator>::Configuration, TResult>
{
public:

	typedef typename generator_traits<TGenerator>::Configuration Configuration;
	typedef std::vector<Configuration> ConfigurationVector;
	typedef std::map<TResult, ConfigurationVector> InvertedTable;
	typedef typename std::map<Configuration, TResult, Comparer> Data;

	void store(const Configuration &c, const TResult &r)
	{
		data[c] = r;
	}

	void getInvertData(std::map<TResult, ConfigurationVector> *ptable)
	{
		for(Data::const_iterator it = data.begin(); it != data.end(); it++)
		{
			InvertedTable::iterator pit = ptable->find(it->second);
			if(pit == ptable->end())
			{
				ConfigurationVector v;
				v.push_back(it->first);
				ptable->insert(InvertedTable::value_type(it->second, v));
			}
			else
			{
				pit->second.push_back(it->first);
			}
		}
	}

	Data data;
};
